package com.ls.demo.tcp.handler;

import com.ls.demo.tcp.namespace.Namespaces;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.AttributeKey;
import io.netty.util.CharsetUtil;
import lombok.extern.java.Log;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * 心跳检测
 * @author liShan
 * @date 2019/8/30 22:27
 */
@Component
@ChannelHandler.Sharable
@Log
public class HeartbeatHandler extends ChannelInboundHandlerAdapter {

    private final ByteBuf query = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer(
            "F1 0D 01 01 3F FF 02 0A 00 00 03 EA 2C F4", CharsetUtil.UTF_8));

    private final Namespaces namespaces = Namespaces.getInstance();

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        AttributeKey<UUID> id = AttributeKey.valueOf("id");
        UUID uuid = ctx.channel().attr(id).get();
        // 发送心跳消息，并在发送失败时关闭该连接
        if (evt instanceof IdleStateEvent) {
            ctx.writeAndFlush(query.duplicate())
                    .addListener(future -> {
                        if (!future.isSuccess()) {
                            log.info(String.format("%s心跳检测失败，关闭连接", uuid));
                            ((ChannelFuture)future).channel().close();
                            namespaces.removeClient(uuid);
                            log.info(String.format("连接断开了,现有连接个数%s", namespaces.size()));
                        }
                    });
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }
}
